package com.lkj.framework.config;

import com.lkj.framework.annotation.GetMapping;
import com.lkj.framework.annotation.RequestMapping;
import com.lkj.framework.annotation.RestController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author likanjia
 */
@Slf4j
public class HandlerControllerConfig {

//    private static HandlerControllerConfig config;

    private List<String> classNames = new ArrayList<String>();

    private Map<String,Object> ioc = new HashMap<>();

    public HandlerControllerConfig(){
        config();
    }

//    public static HandlerControllerConfig getInstance() {
//        if (config == null) {
//            config = new HandlerControllerConfig();
//        }
//        return config;
//    }

    private void config(){
        String packageName = "com.lkj.project";
        doScanner(packageName);
        doInstance();
//        doAutowired();
    }

    private void doScanner(String packageName){

        URL url = this.getClass().getResource("/"+packageName.replaceAll("\\.","/"));
        File dir = new File(url.getFile());

        for (File file : dir.listFiles()) {
            if (file.isDirectory()) {
                doScanner(packageName+"."+file.getName());
            } else {
                String className = packageName + "." + file.getName().replace(".class","");
                classNames.add(className);
            }
        }
    }
//    private void doAutowired(){
//        if (ioc.isEmpty()){
//            return;
//        }
//
//        for (Map.Entry<String, Object> entry : ioc.entrySet()) {
//
//            Field[] fields = entry.getValue().getClass().getDeclaredFields();
//            for (Field field : fields) {
//                if (!field.isAnnotationPresent(Autowired.class)){
//                    continue;
//                }
//                Autowired autowired = field.getAnnotation(Autowired.class);
//                String beanName = autowired.value();
//                if ("".equals(beanName)) {
//                    beanName = field.getType().getName();
//                }
//                field.setAccessible(true);
//
//                try {
//                    field.set(entry.getValue(),ioc.get(beanName));
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//
//    }
    private void doInstance(){

        if (classNames.isEmpty()) {
            return;
        }

        try {
            for (String className : classNames) {

                Class<?> clazz = Class.forName(className);

                if (clazz.isAnnotationPresent(Controller.class)) {

                    String beanName = lowerFirst(clazz.getSimpleName());
                    ioc.put(beanName,clazz.newInstance());
                }
            }
        } catch (Exception e) {

            e.printStackTrace();
        }
    }

    public String doGetMapper(String url,String param){

        try {
            for (String className : classNames) {
                Class<?> clazz = Class.forName(className);

                if (clazz.isAnnotationPresent(Controller.class)) {
                    RequestMapping requestMapping = clazz.getAnnotation(RequestMapping.class);

                    for (Method method : clazz.getMethods()) {

                        GetMapping getMapping = method.getAnnotation(GetMapping.class);

                        String requestValue = requestMapping.value();
                        requestValue = "/".equals(requestValue.substring(0)) ? requestValue : "/"+requestValue;

                        String mapperValue = getMapping.value();
                        mapperValue = "/".equals(mapperValue.substring(0)) ? mapperValue : "/"+mapperValue;

                        String path = requestValue + mapperValue;

                        if (path.equals(url)) {
                            String simpleName = lowerFirst(clazz.getSimpleName());
                            String reslut = (String)method.invoke(ioc.get(simpleName), param);
                            return reslut;
                        }

                    }
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }



    private String lowerFirst(String className) {
        char[] chars = className.toCharArray();
        chars[0] += 32;
        return String.valueOf(chars);
    }
}
